package cn.goour.web.sys.controller.settings

import cn.goour.web.base.`interface`.ValidAdd
import cn.goour.web.base.`interface`.ValidModifying
import cn.goour.web.base.entity.Msg
import cn.goour.web.base.entity.PageInfo
import cn.goour.web.base.exception.BackJsonBeanValidFailException
import cn.goour.web.sys.entity.Admin
import cn.goour.web.sys.entity.type.HttpHeader
import cn.goour.web.sys.service.AdminService
import cn.goour.web.sys.service.RoleGroupService
import decrypt
import encrypt
import getAdmin
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.validation.BindingResult
import org.springframework.validation.Errors
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import javax.annotation.PostConstruct
import javax.servlet.http.HttpServletRequest
import javax.validation.groups.Default

@RestController
@RequestMapping("/admin/settings/admins")
open class AdminController {

    @Autowired private
    lateinit var adminService: AdminService

    @ModelAttribute("admin_id")
    open fun getAdminById(id: Int?): Admin? {
        logger.info("getAdminById($id)")
        if (id != null) {
            return adminService.findOne(id)
        }
        return null
    }

    @GetMapping(headers = arrayOf(HttpHeader.Ajax))
    open fun list(@Validated pageInfo: PageInfo, errors: Errors): Msg {
        if (errors.hasErrors()) {
            throw BackJsonBeanValidFailException(errors)
        }
        val list = adminService.getList(pageInfo)
        return Msg(list)
    }

    @PostMapping("/add", headers = arrayOf(HttpHeader.Ajax))
    open fun add(@Validated(ValidAdd::class, Default::class) admin: Admin, errors: Errors, myPassword: String, password1: String, request: HttpServletRequest): Msg {
        if (errors.hasErrors()) {
            throw BackJsonBeanValidFailException(errors)
        }
        val m = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}\$".toRegex().matches(password1)
        if (!m) {
            throw BackJsonBeanValidFailException("密码必须包含大小写字母和数字的组合，不能使用特殊字符，长度在8-16之间")
        }
        if (myPassword != request.getAdmin().password.decrypt()) {
            throw BackJsonBeanValidFailException("当前用户密码校验失败")
        }
        admin.password = password1
        logger.info("添加：$admin")
        adminService.add(admin)
        return Msg()
    }

    @PutMapping("/update_{id}", headers = arrayOf(HttpHeader.Ajax))
    open fun update(@Validated(ValidModifying::class, Default::class) @ModelAttribute("admin_id") admin: Admin, errors: Errors, myPassword: String, password1: String, request: HttpServletRequest): Msg {
        if (errors.hasErrors()) {
            throw BackJsonBeanValidFailException(errors)
        }
        if (password1.isNotBlank()) {
            val m = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}\$".toRegex().matches(password1)
            if (!m) {
                throw BackJsonBeanValidFailException("密码必须包含大小写字母和数字的组合，不能使用特殊字符，长度在8-16之间")
            }
            admin.password = password1.encrypt()
        }
        if (myPassword != request.getAdmin().password.decrypt()) {
            throw BackJsonBeanValidFailException("当前用户密码校验失败")
        }
        logger.info("修改：$admin")
        adminService.update(admin)
        return Msg()
    }

    @DeleteMapping(headers = arrayOf(HttpHeader.Ajax))
    open fun del(@RequestParam("id[]") id: Array<Int>): Msg {
        val msg = try {
            adminService.delete(id)
            Msg()
        } catch (e: Exception) {
            e.printStackTrace()
            Msg.error(e)
        }
        return msg
    }

    init {
        logger.info("Initialized ${this.javaClass.simpleName}...")
    }

    @PostConstruct
    open fun post() {
        logger.info("PostConstruct ${this.javaClass.simpleName}...")
    }

    companion object {
        private val logger = LoggerFactory.getLogger(AdminController::class.java)
    }
}

@Controller
@RequestMapping("/admin/settings/admins")
open class AdminHtmlController {

    @Autowired private
    lateinit var roleGroupService: RoleGroupService
    @Autowired private
    lateinit var adminService: AdminService

    @RequestMapping("/add")
    open fun adminAdd(model: Model): String {
        model.addAttribute("groups", roleGroupService.findAll())
        model.addAttribute("isUpdate", false)
        model.addAttribute("info", Admin())
        return "web/admin/settings/adminInfo"
    }

    @RequestMapping("/update_{id}")
    open fun adminUpdate(@PathVariable("id") id: Int, model: Model): String {
        model.addAttribute("groups", roleGroupService.findAll())
        model.addAttribute("isUpdate", true)
        model.addAttribute("info", adminService.findOne(id) ?: Admin())
        return "web/admin/settings/adminInfo"
    }

    init {
        logger.info("Initialized ${this.javaClass.simpleName}...")
    }

    @PostConstruct
    open fun post() {
        logger.info("PostConstruct ${this.javaClass.simpleName}...")
    }

    companion object {
        private val logger = LoggerFactory.getLogger(AdminController::class.java)
    }
}